package org.argetr.resim.ui.graphics;

import java.util.ArrayList;

import org.argetr.resim.proc.Processor;
import org.argetr.resim.ui.model.ComponentItem;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.Shape;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;


public class IconFigure extends Shape {

	private Image  _icon;
	private String _displayName;
	private transient ComponentItem _compItem;
	private ArrayList<Integer> _validInputIndices = new ArrayList<Integer>();
	private ArrayList<Integer> _validOutputIndices = new ArrayList<Integer>();
	public static final int PIN_LENGTH = 5;
	private Color _activeColor = ColorConstants.lightGray;
	
	public void setActiveColor(Color color){
		_activeColor = color;
	}
	protected Color getActiveColor(){
		return _activeColor;
	}
	public IconFigure(Image icon,String displayName,ComponentItem componentItem) {
		_icon = icon;
		_displayName = displayName;
		_compItem = componentItem;	
		_compItem.setIconFigure(this);
	}
	public void setValidInputIndices(ArrayList<Integer>  validInputIndices){
		_validInputIndices = validInputIndices;
	}
	public ArrayList<Integer>  getValidInputIndices(){
		return _validInputIndices;
	}
	public void setValidOutputIndices(ArrayList<Integer>  validOutputIndices){
		_validOutputIndices = validOutputIndices;
	}
	public ArrayList<Integer>  getValidOutputIndices(){
		return _validOutputIndices;
	}
	public ArrayList<Point> getOutLocations(){
		int numOutputs = _compItem.getProcessor().getConnectionRule().getNoOutputs();
		int pinDistance = (int)(getBounds().height/(numOutputs+1));
		int x, y;
		ArrayList<Point> points = new ArrayList<Point>();
		for(int pinIndex=0;pinIndex<numOutputs;pinIndex++)
		{							
			x = getBounds().getTopRight().x;
			y =  getBounds().getTopRight().y+pinDistance*(pinIndex+1);
			Point p = new Point(x, y);
			points.add(p);
		}	
		return points;
	}
	public ArrayList<Point> getInLocations(){
		int numInputs = _compItem.getProcessor().getConnectionRule().getNoInputs();
		int pinDistance = (int)(getBounds().height/(numInputs+1));
		int x, y;
		ArrayList<Point> points = new ArrayList<Point>();
		for(int pinIndex=0;pinIndex<numInputs;pinIndex++)
		{							
			x = getBounds().getTopLeft().x;
			y = getBounds().getTopLeft().y+pinDistance*(pinIndex+1);
			Point p = new Point(x, y);
			points.add(p);
		}
		return points;
	}
	public ArrayList<Point> getValidInLocations(){
		int numInputs = _compItem.getProcessor().getConnectionRule().getNoInputs();
		int pinDistance = (int)(getBounds().height/(numInputs+1));
		int x, y;
		ArrayList<Point> points = new ArrayList<Point>();
		for(int pinIndex=0;pinIndex<numInputs;pinIndex++)
		{							
			x = getBounds().getTopLeft().x;
			y = getBounds().getTopLeft().y+pinDistance*(pinIndex+1);
			Point p = new Point(x, y);
			if(_validInputIndices.contains(new Integer(pinIndex)))
			   points.add(p);
		}
		return points;
	}	
	public ArrayList<Point> getValidOutLocations(){
		int numOutputs = _compItem.getProcessor().getConnectionRule().getNoOutputs();
		int pinDistance = (int)(getBounds().height/(numOutputs+1));
		int x, y;
		ArrayList<Point> points = new ArrayList<Point>();
		for(int pinIndex=0;pinIndex<numOutputs;pinIndex++)
		{							
			x = getBounds().getTopRight().x;
			y =  getBounds().getTopRight().y+pinDistance*(pinIndex+1);
			Point p = new Point(x, y);
			if(_validOutputIndices.contains(new Integer(pinIndex)))
				   points.add(p);
		}	
		return points;
	}	
	public void setIcon(Image icon)
	{
		_icon = icon;
	}
	
	public void setDisplayName(String displayName)
	{
	   _displayName = displayName;
	}
	
	public Image getIcon()
	{
		return _icon;
	}
	
	private void drawInputPins(Graphics graphics,int numInputs)
	{
		int pinDistance = (int)(getBounds().height/(numInputs+1));
		int x1,y1,x2,y2;
		for(int pinIndex=0;pinIndex<numInputs;pinIndex++)
		{							
			x1 = getBounds().getTopLeft().x;
			y1 = getBounds().getTopLeft().y+pinDistance*(pinIndex+1);
			x2 = getBounds().getTopLeft().x+PIN_LENGTH;
			y2 = getBounds().getTopLeft().y+pinDistance*(pinIndex+1);
			graphics.drawLine(x1,y1,x2,y2);
		}
	}
	
	private void drawOutputPins(Graphics graphics,int numOutputs)
	{
		int pinDistance = (int)(getBounds().height/(numOutputs+1));
		int x1,y1,x2,y2;
		for(int pinIndex=0;pinIndex<numOutputs;pinIndex++)
		{							
			x1 = getBounds().getTopRight().x-PIN_LENGTH;
			y1 = getBounds().getTopRight().y+pinDistance*(pinIndex+1);
			x2 = getBounds().getTopRight().x;
			y2 =  getBounds().getTopRight().y+pinDistance*(pinIndex+1);
			graphics.drawLine(x1,y1,x2,y2);
		}
	}
	
	protected void fillShape(Graphics graphics) {
		//graphics.drawImage(_icon,getBounds().getTopLeft());
		Point p = getBounds().getTopLeft();
		p.x += 2*PIN_LENGTH;
		p.y += 2*PIN_LENGTH;
		graphics.setBackgroundColor(getActiveColor());
		graphics.fillRoundRectangle(getInnerRectangle(), this.bounds.width/5, this.bounds.height/5);
		graphics.drawText(_displayName, p);
	}

	@Override
	protected void outlineShape(Graphics graphics) {
		graphics.drawRoundRectangle(getInnerRectangle(), this.bounds.width/5, this.bounds.height/5);
		if(_compItem!=null)
		{
			Processor p = _compItem.getProcessor();
			if(p!=null)
			{
			  graphics.setLineWidth(3);	
			  drawInputPins(graphics,p.getConnectionRule().getNoInputs());
			  drawOutputPins(graphics,p.getConnectionRule().getNoOutputs());
			}
		}
	}
	protected Rectangle getInnerRectangle(){
		Rectangle f = Rectangle.SINGLETON;
		Rectangle r = getBounds();
		f.x = r.x + lineWidth / 2 + PIN_LENGTH;
		f.y = r.y + lineWidth / 2 + PIN_LENGTH;
		f.width = r.width - 2*PIN_LENGTH -lineWidth;
		f.height = r.height - 2*PIN_LENGTH- lineWidth;
		return f;
	}
}
